finding optimal solution